package org.bitterorange.flansmodslain.actions;

import org.bitterorange.flansmodslain.FlansModSlain;
import org.bukkit.Server;
import org.bukkit.entity.Player;

import java.util.ArrayList;
import java.util.List;

public class Action {
    private final String ActionId;
    private final List<String> Lines;

    public Action(String actionId, List<String> lines) throws IllegalArgumentException {
        int n = lines.size();
        for (int i = 0; i < n; ++i) {
            if (!isValid(lines.get(i))) {
                throw new IllegalArgumentException(String.format("格式错误位于第%d行 => %s", i, lines.get(i)));
            }
        }
        ActionId = actionId;
        Lines = new ArrayList<>(lines);
    }

    @SuppressWarnings("DuplicateExpressions")
    public static boolean isValid(String line) {
        switch (line.charAt(0)) {
            case 'm':
                if (line.charAt(1) != '+' && line.charAt(1) != '-') {
                    return false;
                }
                try {
                    Double.parseDouble(line.substring(2));
                } catch (NumberFormatException e) {
                    return false;
                }
            case 'p':
                if (line.charAt(1) != '+' && line.charAt(1) != '-') {
                    return false;
                }
                try {
                    Integer.parseInt(line.substring(2));
                } catch (NumberFormatException e) {
                    return false;
                }
            case '<':
            case '>':
                return line.length() > 1;
            default:
                return false;
        }
    }

    public String getActionId() {
        return ActionId;
    }

    public int countOfLines() {
        return Lines.size();
    }

    public String lineAt(int index) throws IndexOutOfBoundsException {
        return Lines.get(index);
    }

    public Response doActionTo(Player player) {
        double moneyAdded = 0.0D;
        int pointsAdded = 0;
        for (String line : Lines) {
            switch (line.charAt(0)) {
                case 'm':
                    if (line.charAt(1) == '+') {
                        double amount = Double.parseDouble(line.substring(2));
                        Money.give(player, amount);
                        moneyAdded += amount;
                    } else {
                        double amount = Double.parseDouble(line.substring(2));
                        if (Money.has(player, amount)) {
                            Money.take(player, amount);
                            moneyAdded -= amount;
                        } else {
                            double balance = Money.balanceOf(player);
                            Money.take(player, balance);
                            moneyAdded -= balance;
                            player.sendMessage("§6Money 不足！你的余额已被设置为§c0§6。");
                        }
                    }
                    break;
                case 'p':
                    int points = Integer.parseInt(line.substring(2));
                    if (line.charAt(1) == '+') {
                        Point.add(player, points);
                        pointsAdded += points;
                    } else {
                        Point.add(player, -points);
                        pointsAdded -= points;
                    }
                    break;
                case '<':
                    player.performCommand(line.substring(1));
                    break;
                case '>':
                    Server server = FlansModSlain.getBukkitServer();
                    server.dispatchCommand(server.getConsoleSender(), line.substring(1).replace("%player%", player.getName()));
                    break;
            }
        }
        return new Response(moneyAdded, pointsAdded);
    }

    @Override
    public String toString() {
        return "Action{" +
                "ActionId='" + ActionId + '\'' +
                ", Lines=" + Lines.toString() +
                '}';
    }

    @SuppressWarnings("InnerClassMayBeStatic")
    public class Response {
        private final double MoneyAdded;
        private final int PointsAdded;

        public Response(double moneyAdded, int pointsAdded) {
            MoneyAdded = moneyAdded;
            PointsAdded = pointsAdded;
        }

        public double getMoneyAdded() {
            return MoneyAdded;
        }

        public int getPointsAdded() {
            return PointsAdded;
        }
    }
}
